<script setup lang="ts">
import { ref } from 'vue';
import { useRestorationStore } from '../../stores/restorationStore';
import imageRestorationService from '../../services/ImageRestorationService';
import { parseMetadata } from '../../utils/metadataUtils';
import { readFileAsText } from '../../utils/fileUtils';
import { handleError, ValidationError, ProcessingError } from '../../utils/errorUtils';

const restorationStore = useRestorationStore();
const fileInput = ref<HTMLInputElement | null>(null);
const metadataInput = ref<HTMLInputElement | null>(null);
const isDragging = ref(false);
const errorMessage = ref<string | null>(null);
const showError = ref(false);

// 清空上传的拼接图片和元数据，准备下一次还原操作
function clearUploadedFiles() {
  if (confirm('确定要清空已上传的图片和元数据吗？')) {
    restorationStore.stitchedImageFile = null;
    restorationStore.metadata = null;
    restorationStore.validationResult = null;
    
    // 如果有文件输入框，重置它们
    if (fileInput.value) fileInput.value.value = '';
    if (metadataInput.value) metadataInput.value.value = '';
    
    // 清除错误信息
    errorMessage.value = null;
    showError.value = false;
  }
}

async function handleImageSelect(event: Event) {
  const input = event.target as HTMLInputElement;
  if (input.files && input.files.length > 0) {
    const file = input.files[0];

    // Clear previous error
    errorMessage.value = null;
    showError.value = false;

    // Check if file is an image
    if (!file.type.startsWith('image/')) {
      errorMessage.value = '请选择有效的图片文件';
      showError.value = true;
      return;
    }

    // Set uploaded stitched image
    restorationStore.setUploadedStitchedImage(file);

    // If metadata is already uploaded, validate it against the image
    if (restorationStore.metadata) {
      validateMetadataWithImage();
    }
  }
}

async function handleMetadataSelect(event: Event) {
  const input = event.target as HTMLInputElement;
  if (input.files && input.files.length > 0) {
    const file = input.files[0];

    // Clear previous error
    errorMessage.value = null;
    showError.value = false;

    try {
      // Read metadata file
      const metadataText = await readFileAsText(file);

      // Parse metadata
      const result = parseMetadata(metadataText);

      if (!result.valid) {
        errorMessage.value = result.message || '元数据格式无效';
        showError.value = true;
        return;
      }

      // Set uploaded metadata
      if (result.metadata) {
        restorationStore.setUploadedMetadata(result.metadata);
      }

      // If image is already uploaded, validate metadata against the image
      if (restorationStore.stitchedImageFile) {
        validateMetadataWithImage();
      }
    } catch (error: any) {
      console.error('读取元数据文件失败:', error);
      errorMessage.value = '读取元数据文件失败: ' + error.message;
      showError.value = true;
    }
  }
}

async function validateMetadataWithImage() {
  if (!restorationStore.stitchedImageFile || !restorationStore.metadata) {
    return;
  }

  try {
    // Validate metadata against image
    const validation = await imageRestorationService.validateMetadata(
      restorationStore.stitchedImageFile,
      restorationStore.metadata
    );

    if (!validation.valid) {
      errorMessage.value = validation.message || '元数据与图片不匹配';
      showError.value = true;

      // Clear metadata if validation fails
      restorationStore.setUploadedMetadata(null);
    }
  } catch (error: any) {
    console.error('验证元数据失败:', error);
    errorMessage.value = '验证元数据失败: ' + error.message;
    showError.value = true;

    // Clear metadata if validation fails
    restorationStore.setUploadedMetadata(null);
  }
}

function openImageDialog() {
  if (fileInput.value) {
    fileInput.value.click();
  }
}

function openMetadataDialog() {
  if (metadataInput.value) {
    metadataInput.value.click();
  }
}

function handleDragOver(event: DragEvent) {
  event.preventDefault();
  isDragging.value = true;
}

function handleDragLeave() {
  isDragging.value = false;
}

function handleDrop(event: DragEvent) {
  event.preventDefault();
  isDragging.value = false;

  if (event.dataTransfer?.files && event.dataTransfer.files.length > 0) {
    // Process dropped files
    for (let i = 0; i < event.dataTransfer.files.length; i++) {
      const file = event.dataTransfer.files[i];

      // Check if file is an image
      if (file.type.startsWith('image/')) {
        // Handle as image
        restorationStore.setUploadedStitchedImage(file);

        // If metadata is already uploaded, validate it against the image
        if (restorationStore.metadata) {
          validateMetadataWithImage();
        }
      }
      // Check if file is JSON
      else if (file.type === 'application/json' || file.name.endsWith('.json')) {
        // Handle as metadata
        handleMetadataFile(file);
      }
    }
  }
}

async function handleMetadataFile(file: File) {
  try {
    // Read metadata file
    const metadataText = await readFileAsText(file);

    // Parse metadata
    const result = parseMetadata(metadataText);

    if (!result.valid) {
      errorMessage.value = result.message || '元数据格式无效';
      showError.value = true;
      return;
    }

    // Set uploaded metadata
    if (result.metadata) {
      restorationStore.setUploadedMetadata(result.metadata);
    }

    // If image is already uploaded, validate metadata against the image
    if (restorationStore.stitchedImageFile) {
      validateMetadataWithImage();
    }
  } catch (error: any) {
    console.error('读取元数据文件失败:', error);
    errorMessage.value = '读取元数据文件失败: ' + error.message;
    showError.value = true;
  }
}

async function startRestoration() {
  if (!restorationStore.stitchedImageFile || !restorationStore.metadata) {
    errorMessage.value = '请先上传拼接图片和元数据';
    showError.value = true;
    return;
  }

  // Clear previous error
  errorMessage.value = null;
  showError.value = false;

  // Set restoring state
  restorationStore.setRestoring(true);

  try {
    // Start restoration process
    const restoredImages = await imageRestorationService.restoreImages(
      restorationStore.stitchedImageFile,
      restorationStore.metadata,
      (progress) => {
        restorationStore.setRestorationProgress(progress);
      }
    );

    // Set restored images
    restorationStore.setRestoredImages(restoredImages);
  } catch (error: any) {
    console.error('还原图片失败:', error);

    // Handle different types of errors
    if (error instanceof ValidationError) {
      errorMessage.value = error.message || '元数据验证失败，请检查元数据是否与图片匹配。';
    } else if (error instanceof ProcessingError) {
      errorMessage.value = error.message || '还原过程中出错，请重试。';
    } else {
      errorMessage.value = handleError(error);
    }

    showError.value = true;
  } finally {
    // Reset restoring state
    restorationStore.setRestoring(false);
  }
}
</script>

<template>
  <div class="restoration-controls">
    <div class="upload-header">
      <h3>还原图片</h3>
      <button 
        v-if="restorationStore.stitchedImageFile || restorationStore.metadata"
        @click="clearUploadedFiles" 
        class="clear-button"
        aria-label="清空上传的图片和元数据"
      >
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24">
          <path fill="currentColor" d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/>
        </svg>
        清空上传
      </button>
    </div>
    
    <div class="upload-area" :class="{ dragging: isDragging }" @dragover="handleDragOver" @dragleave="handleDragLeave"
      @drop="handleDrop">
      <div class="upload-section">
        <h4>上传拼接图片</h4>
        <div v-if="restorationStore.stitchedImageFile" class="file-info">
          <p>{{ restorationStore.stitchedImageFile.name }}</p>
        </div>
        <div v-else class="upload-placeholder">
          <div class="upload-icon">
            <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24">
              <path fill="currentColor"
                d="M19.35 10.04A7.49 7.49 0 0 0 12 4C9.11 4 6.6 5.64 5.35 8.04A5.994 5.994 0 0 0 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5c0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5l5 5h-3z" />
            </svg>
          </div>
          <p>拖放拼接图片到此处或</p>
          <button @click="openImageDialog" aria-label="选择拼接图片" tabindex="0" @keydown.enter="openImageDialog"
            @keydown.space="openImageDialog">
            选择图片
          </button>
          <input ref="fileInput" type="file" accept="image/jpeg,image/png,image/webp" @change="handleImageSelect"
            style="display: none" aria-hidden="true">
        </div>
      </div>

      <div class="upload-section">
        <h4>上传元数据</h4>
        <div v-if="restorationStore.metadata" class="file-info">
          <p>元数据已上传</p>
        </div>
        <div v-else class="upload-placeholder">
          <div class="upload-icon">
            <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24">
              <path fill="currentColor"
                d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z" />
            </svg>
          </div>
          <p>拖放元数据文件到此处或</p>
          <button @click="openMetadataDialog" aria-label="选择元数据文件" tabindex="0" @keydown.enter="openMetadataDialog"
            @keydown.space="openMetadataDialog">
            选择文件
          </button>
          <input ref="metadataInput" type="file" accept="application/json" @change="handleMetadataSelect"
            style="display: none" aria-hidden="true">
        </div>
      </div>
    </div>

    <!-- 质量控制选项 -->
    <div class="quality-controls" v-if="restorationStore.stitchedImageFile && restorationStore.metadata">
      <h4>还原质量设置</h4>
      
      <div class="quality-option">
        <label>
          <input type="checkbox" v-model="restorationStore.preserveFormat">
          保留原始图片格式
        </label>
      </div>
      
      <div class="quality-slider">
        <label>JPEG质量: {{ Math.round(restorationStore.jpegQuality * 100) }}%</label>
        <input 
          type="range" 
          min="10" 
          max="100" 
          :value="restorationStore.jpegQuality * 100" 
          @input="e => restorationStore.setJpegQuality(Number((e.target as HTMLInputElement).value) / 100)"
        >
      </div>
      
      <div class="quality-slider">
        <label>PNG质量: {{ Math.round(restorationStore.pngQuality * 100) }}%</label>
        <input 
          type="range" 
          min="10" 
          max="100" 
          :value="restorationStore.pngQuality * 100" 
          @input="e => restorationStore.setPngQuality(Number((e.target as HTMLInputElement).value) / 100)"
        >
      </div>
      
      <div class="quality-info">
        <p>提示: 更高的质量会产生更大的文件，更低的质量可能会导致图片细节丢失。</p>
      </div>
    </div>

    <button class="restore-button"
      :disabled="!restorationStore.stitchedImageFile || !restorationStore.metadata || restorationStore.isRestoring"
      @click="startRestoration" aria-label="开始还原图片" :aria-busy="restorationStore.isRestoring"
      :aria-disabled="!restorationStore.stitchedImageFile || !restorationStore.metadata">
      开始还原
    </button>

    <div v-if="restorationStore.isRestoring" class="restoration-progress">
      <div class="loading-spinner">
        <div class="spinner"></div>
      </div>
      <p>还原中...</p>
    </div>

    <div v-if="showError" class="error-message">
      <p>{{ errorMessage }}</p>
    </div>
  </div>
</template>

<style scoped>
.restoration-controls {
  margin-top: 2rem;
}

.upload-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
}

h3 {
  margin: 0;
}

.clear-button {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.4rem 0.8rem;
  background-color: #f44336;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 0.9rem;
}

.clear-button:hover {
  background-color: #d32f2f;
}

.upload-area {
  display: flex;
  gap: 1rem;
  margin-bottom: 1.5rem;
  border: 2px dashed #ccc;
  border-radius: 8px;
  padding: 1.5rem;
  transition: all 0.3s ease;
}

/* Responsive styles */
@media (max-width: 768px) {
  .upload-area {
    flex-direction: column;
    gap: 1.5rem;
    padding: 1rem;
  }
}

.upload-area.dragging {
  border-color: #4caf50;
  background-color: rgba(76, 175, 80, 0.1);
}

.upload-section {
  flex: 1;
  display: flex;
  flex-direction: column;
}

h4 {
  margin-top: 0;
  margin-bottom: 1rem;
}

.upload-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 1.5rem;
  background-color: #f5f5f5;
  border-radius: 4px;
  text-align: center;
}

.upload-icon {
  color: #666;
}

.file-info {
  padding: 1.5rem;
  background-color: #e8f5e9;
  border-radius: 4px;
  text-align: center;
}

button {
  padding: 0.5rem 1rem;
  background-color: #4caf50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 1rem;
}

button:hover:not(:disabled) {
  background-color: #45a049;
}

.restore-button {
  width: 100%;
  padding: 0.75rem;
  font-size: 1rem;
}

.restore-button:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

.restoration-progress {
  margin-top: 1rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}

.loading-spinner {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 0.5rem;
}

.spinner {
  width: 40px;
  height: 40px;
  border: 4px solid rgba(76, 175, 80, 0.3);
  border-radius: 50%;
  border-top-color: #4caf50;
  animation: spin 1s ease-in-out infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.quality-controls {
  margin-bottom: 1.5rem;
  padding: 1rem;
  background-color: #f5f5f5;
  border-radius: 8px;
  border: 1px solid #e0e0e0;
}

.quality-option {
  margin-bottom: 1rem;
}

.quality-option label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
}

.quality-slider {
  margin-bottom: 1rem;
}

.quality-slider label {
  display: block;
  margin-bottom: 0.5rem;
  font-weight: 500;
}

.quality-slider input[type="range"] {
  width: 100%;
  height: 8px;
  border-radius: 4px;
  background: #ddd;
  outline: none;
  -webkit-appearance: none;
}

.quality-slider input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #4caf50;
  cursor: pointer;
}

.quality-slider input[type="range"]::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #4caf50;
  cursor: pointer;
  border: none;
}

.quality-info {
  padding: 0.75rem;
  background-color: #e8f5e9;
  border-radius: 4px;
  font-size: 0.9rem;
}

.quality-info p {
  margin: 0;
}

.error-message {
  margin-top: 1rem;
  padding: 0.75rem;
  background-color: #ffebee;
  border: 1px solid #ffcdd2;
  border-radius: 4px;
  color: #c62828;
}
</style>